package cn.h8k.hj212.version.impl;

import cn.h8k.hj212.codec.impl.DefaultHj212EntityCodec;
import cn.h8k.hj212.codec.impl.DefaultHj212Validator;
import cn.h8k.hj212.constant.Hj212Constants;
import cn.h8k.hj212.entity.Hj212Message;
import cn.h8k.hj212.version.ProtocolVersion;
import cn.h8k.hj212.version.VersionAdapter;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;

import java.util.HashMap;
import java.util.Map;
import java.util.regex.Pattern;

/**
 * HJ212-2017协议版本适配器
 * 
 * @author HJ212 Team
 * @since 1.0
 */
public class Hj212_2017_Adapter implements VersionAdapter {
    
    private static final Logger logger = LoggerFactory.getLogger(Hj212_2017_Adapter.class);
    
    private static final Pattern HJ212_2017_PATTERN = Pattern.compile(
        "^##\\d{4}QN=\\d{17};ST=\\d{2};CN=\\d{4};.*&&.*&&[0-9A-Fa-f]{4}\\r\\n$"
    );
    
    private final DefaultHj212EntityCodec entityCodec;
    private final Map<String, Object> versionConstants;
    private final Map<String, String> fieldMappings;
    
    public Hj212_2017_Adapter() {
        this.entityCodec = new DefaultHj212EntityCodec(new DefaultHj212Validator());
        this.versionConstants = initializeVersionConstants();
        this.fieldMappings = initializeFieldMappings();
    }
    
    @Override
    public ProtocolVersion getSupportedVersion() {
        return ProtocolVersion.HJ212_2017;
    }
    
    @Override
    public boolean isCompatible(String protocolData) {
        if (protocolData == null || protocolData.trim().isEmpty()) {
            return false;
        }
        
        try {
            // 基本格式检查
            if (!protocolData.startsWith(Hj212Constants.HEAD) || 
                !protocolData.endsWith(Hj212Constants.LINE_ENDING)) {
                return false;
            }
            
            // 长度检查
            if (protocolData.length() < 20) {
                return false;
            }
            
            // 详细格式检查
            return HJ212_2017_PATTERN.matcher(protocolData).matches();
            
        } catch (Exception e) {
            logger.debug("协议兼容性检查失败", e);
            return false;
        }
    }
    
    @Override
    public String adaptToStandard(String protocolData) {
        // HJ212-2017已经是标准格式，直接返回
        return protocolData;
    }
    
    @Override
    public String adaptFromStandard(String standardData) {
        // HJ212-2017已经是标准格式，直接返回
        return standardData;
    }
    
    @Override
    public Hj212Message parseMessage(String protocolData) {
        try {
            return entityCodec.decode(protocolData);
        } catch (Exception e) {
            logger.error("解析HJ212-2017协议消息失败", e);
            throw new RuntimeException("解析协议消息失败: " + e.getMessage(), e);
        }
    }
    
    @Override
    public String formatMessage(Hj212Message message) {
        try {
            return entityCodec.encode(message);
        } catch (Exception e) {
            logger.error("格式化HJ212-2017协议消息失败", e);
            throw new RuntimeException("格式化协议消息失败: " + e.getMessage(), e);
        }
    }
    
    @Override
    public Map<String, Object> getVersionConstants() {
        return new HashMap<>(versionConstants);
    }
    
    @Override
    public ValidationResult validateProtocol(String protocolData) {
        if (protocolData == null || protocolData.trim().isEmpty()) {
            return ValidationResult.failure("协议数据不能为空", "EMPTY_DATA", getSupportedVersion());
        }
        
        // 检查基本格式
        if (!isCompatible(protocolData)) {
            return ValidationResult.failure("协议格式不符合HJ212-2017标准", "INVALID_FORMAT", getSupportedVersion());
        }
        
        try {
            // 尝试解析消息
            parseMessage(protocolData);
            return ValidationResult.success(getSupportedVersion());
            
        } catch (Exception e) {
            return ValidationResult.failure("协议解析失败: " + e.getMessage(), "PARSE_ERROR", getSupportedVersion());
        }
    }
    
    @Override
    public Map<String, String> getFieldMappings() {
        return new HashMap<>(fieldMappings);
    }
    
    @Override
    public String mapFieldName(String oldFieldName) {
        return fieldMappings.getOrDefault(oldFieldName, oldFieldName);
    }
    
    @Override
    public Object mapFieldValue(String fieldName, Object oldValue) {
        // HJ212-2017版本的字段值映射逻辑
        if (oldValue == null) {
            return null;
        }
        
        switch (fieldName) {
            case Hj212Constants.ST:
                // 系统编号映射
                return mapSystemType(oldValue.toString());
                
            case Hj212Constants.CN:
                // 命令编号映射
                return mapCommandNumber(oldValue.toString());
                
            case Hj212Constants.FLAG:
                // 标志位映射
                return mapFlag(oldValue.toString());
                
            default:
                return oldValue;
        }
    }
    
    /**
     * 初始化版本常量
     */
    private Map<String, Object> initializeVersionConstants() {
        Map<String, Object> constants = new HashMap<>();
        
        // 协议版本信息
        constants.put("VERSION", "HJ212-2017");
        constants.put("VERSION_CODE", "2017");
        
        // 协议格式常量
        constants.put("HEADER", Hj212Constants.HEAD);
        constants.put("LINE_ENDING", Hj212Constants.LINE_ENDING);
        constants.put("FIELD_SEPARATOR", Hj212Constants.FIELD_SEPARATOR);
        constants.put("GROUP_SEPARATOR", Hj212Constants.GROUP_SEPARATOR);
        constants.put("ITEM_SEPARATOR", Hj212Constants.ITEM_SEPARATOR);
        constants.put("KEY_VALUE_SEPARATOR", Hj212Constants.KEY_VALUE_SEPARATOR);
        
        // 时间戳格式
        constants.put("TIMESTAMP_FORMAT", Hj212Constants.TIMESTAMP_FORMAT);
        constants.put("LENGTH_FORMAT", Hj212Constants.LENGTH_FORMAT);
        
        // 支持的系统编号
        constants.put("SUPPORTED_SYSTEM_TYPES", new String[]{
            "21", "22", "23", "24", "25", "26", "27",  // 环境质量监测
            "31", "32", "33", "34", "35", "36", "37", "38", "39", "41",  // 污染源监测
            "51", "52",  // 过程监控
            "91"  // 系统交互
        });
        
        // 支持的命令编号
        constants.put("SUPPORTED_COMMAND_NUMBERS", new String[]{
            "1011", "1012", "1013", "1014",  // 初始化命令
            "2011", "2012", "2013", "2014",  // 数据上报命令
            "3011", "3012", "3013", "3014",  // 控制命令
            "9011", "9012", "9013", "9014"   // 交互命令
        });
        
        return constants;
    }
    
    /**
     * 初始化字段映射
     */
    private Map<String, String> initializeFieldMappings() {
        Map<String, String> mappings = new HashMap<>();
        
        // HJ212-2017版本的字段名映射（如果需要从其他版本转换）
        mappings.put("QN", Hj212Constants.QN);
        mappings.put("ST", Hj212Constants.ST);
        mappings.put("CN", Hj212Constants.CN);
        mappings.put("PW", Hj212Constants.PW);
        mappings.put("MN", Hj212Constants.MN);
        mappings.put("Flag", Hj212Constants.FLAG);
        mappings.put("CP", Hj212Constants.CP);
        
        return mappings;
    }
    
    /**
     * 映射系统类型
     */
    private String mapSystemType(String systemType) {
        // 可以在这里添加系统类型的映射逻辑
        return systemType;
    }
    
    /**
     * 映射命令编号
     */
    private String mapCommandNumber(String commandNumber) {
        // 可以在这里添加命令编号的映射逻辑
        return commandNumber;
    }
    
    /**
     * 映射标志位
     */
    private String mapFlag(String flag) {
        // 可以在这里添加标志位的映射逻辑
        return flag;
    }
}
